﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SmokinAces.Object_Classes.Objects
{
    class Fireball : Game_Object, Draw_Object, Logic_Object
    {
        public Sort_Delegate drawSortDelegate;
        VertexPositionColorTexture[] baseImage;
        VertexPositionColorTexture[] vertecies;
        int fireballIndex;
        int[] indecies;
        const float zorder = 1.0f;
        private const float divider = 1.0f / 12;

        public Fireball(int left, int top, Main_Engine Parent)
        {
            Initialize(left, top, left + 30, top + 30, Parent);
        }
        public Fireball(XmlReader xmlReader, Main_Engine Parent)
        {
            xmlReader.Read();
            string sLeft = xmlReader.ReadElementString("Left");
            string sTop = xmlReader.ReadElementString("Top");
            //------------------------------------
            int left = Convert.ToInt32(sLeft);
            int top = Convert.ToInt32(sTop);
            
            Initialize(left, top, left + 30, top + 30,  Parent);
        }
        public override bool Save_XML(XmlTextWriter textWriter)
        {
            try
            {
                textWriter.WriteStartElement("Game_Object");
                textWriter.WriteAttributeString("Type", this.GetType().AssemblyQualifiedName);
                textWriter.WriteElementString("Left", baseImage[0].Position.X.ToString());
                textWriter.WriteElementString("Top", baseImage[0].Position.Y.ToString());
                textWriter.WriteEndElement();
                textWriter.Flush();
            }
            catch
            {
                return false;
            }
            return true;
        }
        private void Initialize(int left, int top, int right, int bottom, Main_Engine parent)
        {
            this.parent = parent;
            GraphicBB = new BoundingBox(new Vector3(left, top, Util.MinZ), new Vector3(right, bottom, Util.MaxZ));
            this.fireballIndex = parent.register_texture("fireball.png");
            float width = right - left;
            float height = bottom - top;

            Color baseColor = new Color(255, 255, 255, 255);

            baseImage = new VertexPositionColorTexture[4];
            baseImage[0].Position = new Vector3(left, top, zorder);
            baseImage[0].Color = baseColor;
            baseImage[0].TextureCoordinate = new Vector2(divider, 0.99f);
            baseImage[1].Position = new Vector3(left, bottom, zorder);
            baseImage[1].Color = baseColor;
            baseImage[1].TextureCoordinate = new Vector2(divider, 0.0f);
            baseImage[2].Position = new Vector3(right, top, zorder);
            baseImage[2].Color = baseColor;
            baseImage[2].TextureCoordinate = new Vector2(0.0f, 0.99f);
            baseImage[3].Position = new Vector3(right, bottom, zorder);
            baseImage[3].Color = baseColor;
            baseImage[3].TextureCoordinate = new Vector2(0.0f, 0.0f);

            vertecies = Util.ComplexMesh(baseImage, out indecies, 4, 4);
            Bounding_Regions.Add(new BoundingBox(new Vector3(left + 8, top + 8 + 0, -1), new Vector3(left + 20, top + 20, 1)));
            Bounding_Weapon.Add(new BoundingBox(new Vector3(left + 8, top + 8 + 0, -1), new Vector3(left + 20, top + 20, 1)));
            drawSortDelegate = new Sort_Delegate(((1024 - top) * 1024) + left, Draw);
            SoundManager.PlaySound("FireBall");
        }

        #region Draw_Object Members
        public void Draw(GameTime gameTime, GraphicsDevice device)
        {
                //---Set the Texture for this layer
                parent.effect.BaseTexture = parent.Texture_List[fireballIndex];
                //---------Begin the drawing passes
                parent.effect.Begin();
                foreach (EffectPass pass in parent.effect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    //device.DrawUserPrimitives(PrimitiveType.TriangleStrip, baseImage, 0, 2);
                    device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertecies, 0, vertecies.Length, indecies, 0, indecies.Length / 3);
                    pass.End();
                }
                parent.effect.End();
        }

        public bool startDraw()
        {
            parent.Draw_Functions[3].Add(drawSortDelegate);
            return true;
        }
        public bool stopDraw()
        {
            parent.Draw_Functions[3].Remove(drawSortDelegate);
            return true;
        }
        #endregion

        #region Game_Object Members
        public override bool dispose()
        {
            //----------------I used some basic boolean logic here...
            stopDraw();
            return parent.Draw_Functions[3].Remove(drawSortDelegate);
        }
        #endregion

        #region Logic_Object Members

        public int direction = 1;
        public int distance = 50;
        int loop = 1;
        double LastAnimation = 0.0;
        int update = 0;
        int[] DownAnimationList = { 2, 1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 2 };
        int[] UpAnimationList = { 5, 4, 4, 4, 5, 5, 5, 6, 6, 6, 5, 5 };
        int[] LeftAnimationList = { 9, 8, 7, 7, 8, 9, 9, 8, 7, 7, 8, 9 };
        int[] RightAnimationList = { 10, 12, 11, 11, 12, 10, 10, 11, 11, 12, 12, 10 };
        Vector3 Speed = Vector3.Zero;
        
        public void Update(GameTime gameTime)
        {
            if (explosiontime > 0)
            {
                if (gameTime.TotalGameTime.TotalMilliseconds > LastAnimation + update)
                {
                    LastAnimation = gameTime.TotalGameTime.TotalMilliseconds;
                    explosiontime--;
                }
                if (explosiontime <= 0)
                {
                    parent.MapObjects.Remove(this);
                }
                return;

            }
            updateBoundingRegions(Speed);
            if (this.isColliding())
            {
                this.explode();
            }
            else
            {
                if (gameTime.TotalGameTime.TotalMilliseconds > LastAnimation + update)
                {
                    LastAnimation = gameTime.TotalGameTime.TotalMilliseconds;

                    if (distance > 0)
                    {
                        if (direction == 0)
                        {
                            Speed.X = 8;
                            Speed.Y = 0;
                        }
                        else if (direction == 1)
                        {
                            Speed.X = -8;
                            Speed.Y = 0;
                        }
                        else if (direction == 2)
                        {
                            Speed.X = 0;
                            Speed.Y = 5;
                        }
                        else if (direction == 3)
                        {
                            Speed.X = 0;
                            Speed.Y = -5;
                        }
                        distance--;
                        loop++;
                        if (loop > 11)
                        {
                            loop = 0;
                        }

                        switch (direction)
                        {
                            case 0:
                                recalculate(RightAnimationList);
                                break;
                            case 1:
                                recalculate(LeftAnimationList);
                                break;
                            case 2:
                                recalculate(UpAnimationList);
                                break;
                            case 3:
                                recalculate(DownAnimationList);
                                break;
                        }
                    }
                    else
                    {
                        parent.MapObjects.Remove(this);
                    }

                }
            }
        }
        int explosiontime = 0;
        private void explode()
        {
            explosiontime = 5;
            SoundManager.PlaySound("FireBallHit");
        }
        private void recalculate(int[] AnimationList)
        {
            float offset = AnimationList[loop] * divider;
            
                drawSortDelegate = new Sort_Delegate(((1024 - GraphicBB.Min.Y) * 1024) + GraphicBB.Min.X, Draw);
                baseImage[0].Position += Speed;
                baseImage[1].Position += Speed;
                baseImage[2].Position += Speed;
                baseImage[3].Position += Speed;
            vertecies = Util.ComplexMesh(baseImage, out indecies, 4, 4);
            baseImage[0].TextureCoordinate = new Vector2(offset, 0.99f);
            baseImage[1].TextureCoordinate = new Vector2(offset, 0.0f);
            baseImage[2].TextureCoordinate = new Vector2(offset - divider, 0.99f);
            baseImage[3].TextureCoordinate = new Vector2(offset - divider, 0.0f);

            vertecies = Util.ComplexMesh(baseImage, out indecies, 4, 4);
            //------------This is to update the quadtree
            parent.MapObjects.Remove(this);
            parent.MapObjects.Add(this);
            //-------------------------------------------
        }

        public bool stopUpdate()
        {
            parent.remove_Update_Object(Update);
            return true;
        }

        public bool startUpdate()
        {
            parent.add_Update_Object(Update);
            return true;
        }
        #endregion
    }
}
